/*
 * Copyright (c) 2024 OpenHiTLS. All rights reserved.
 * Licensed under the OpenHiTLS license.
 */
package org.openhitls.tls;

import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * SSLSocketFactory implementation backed by openHiTLS.
 *
 * <p>This factory creates SSL sockets that wrap plain sockets with TLS.</p>
 */
public class HiTlsSSLSocketFactory extends SSLSocketFactory {

    private final HiTlsSSLContextSpi context;

    HiTlsSSLSocketFactory(HiTlsSSLContextSpi context) {
        this.context = context;
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return context.getEnabledCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return context.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose)
            throws IOException {
        return new HiTlsSSLSocket(context, s, host, port, autoClose);
    }

    @Override
    public Socket createSocket(String host, int port)
            throws IOException, UnknownHostException {
        HiTlsSSLSocket socket = new HiTlsSSLSocket(context);
        socket.connect(host, port);
        return socket;
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
            throws IOException, UnknownHostException {
        HiTlsSSLSocket socket = new HiTlsSSLSocket(context);
        socket.bind(localHost, localPort);
        socket.connect(host, port);
        return socket;
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        HiTlsSSLSocket socket = new HiTlsSSLSocket(context);
        socket.connect(host, port);
        return socket;
    }

    @Override
    public Socket createSocket(InetAddress address, int port,
                               InetAddress localAddress, int localPort) throws IOException {
        HiTlsSSLSocket socket = new HiTlsSSLSocket(context);
        socket.bind(localAddress, localPort);
        socket.connect(address, port);
        return socket;
    }

    @Override
    public Socket createSocket() throws IOException {
        return new HiTlsSSLSocket(context);
    }

    @Override
    public Socket createSocket(Socket s, InputStream consumed, boolean autoClose)
            throws IOException {
        return new HiTlsSSLSocket(context, s, consumed, autoClose);
    }
}
